﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;


using DotSpatial.Topology;



using DotSpatial.Data;

using DotSpatial.Symbology;
using DotSpatial.Symbology.Forms;

using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

using System.ComponentModel;
using System.ComponentModel.Design;
using System.IO;

using DotSpatial.Controls;


namespace HaGisPack
{
    [Serializable ]
    public abstract  class FShapeLayer : FLayer
    {
        public FShapeLayer(string id)
            : base(id)
        {

            this.m_bSelectable = true;

        }



        #region 公用变化信息

        public IFeatureLayer IFLayer
        {
            get { return (IFeatureLayer)this.ILayer; }
        }

        [NonSerialized]
        protected object _LabelLayer = new MapLabelLayer();

        [Editor(typeof(LabelSetupEditor), typeof(UITypeEditor))]
        [Category("标注设置"), DisplayName("标注设置")]
        public virtual object LabelLayer
        {
            get
            {
                if ((this.ILayer as DotSpatial.Controls.IMapFeatureLayer).LabelLayer == null)
                {
                    (this.ILayer as IMapFeatureLayer).LabelLayer = new MapLabelLayer();
                    (this.ILayer as DotSpatial.Controls.IMapFeatureLayer).ShowLabels = true;                    
                }
                this._LabelLayer = (this.ILayer as DotSpatial.Controls.IMapFeatureLayer).LabelLayer;
                return _LabelLayer; 
            }
            set 
            { 
                _LabelLayer = value;
                (this.ILayer as DotSpatial.Controls.IMapFeatureLayer).LabelLayer = (MapLabelLayer)this._LabelLayer;
                //this.m_ParenLManager.CurrentMap.MapFrame.Invalidate();
                //this.ILayer.Invalidate();
            }
        }


        #endregion



        #region 公用配置信息


        /// <summary>
        /// 用于初始化shape相关的选项
        /// </summary>
        public virtual void Configure()
        {


            DataSet = new FeatureSet(this.m_Type);

            this.DataSet.Projection = DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984;

            DataColumn dcId = new DataColumn("id",typeof (string));

            DataColumn dcDesc = new DataColumn("desc",typeof (string));



            (this.DataSet as IFeatureSet).DataTable.Columns.Add(dcId );
            (this.DataSet as IFeatureSet).DataTable.Columns.Add(dcDesc);

            (this.DataSet as IFeatureSet).DataTable.TableName =this.Id ;
          


        }

        #endregion


        /// <summary>
        /// 返回当前层的选择feature
        /// </summary>
        /// <returns></returns>
        public List <IFeature > GetSelectionFeatures()
        {
           return  this.IFLayer.Selection.ToFeatureList();
        }
 

        /// <summary>
        /// 用于存储对应的图形
        /// </summary>
        Dictionary<string, FShape> m_Shapes = new Dictionary<string, FShape>();

        [Browsable(false)]
        public Dictionary<string, FShape> Shapes
        {
            get { return m_Shapes; }
            set { m_Shapes = value; }
        }



        /// <summary>
        /// 用于保存当前图形的类型,type将根据子类型来确定
        /// </summary>
      protected  FeatureType  m_Type;
     

     


        protected  override void BuildLayer()
        {

            base.BuildLayer();
            
            
            this.ILayer = this.m_ParenLManager.CurrentMap.Layers.Add(this.DataSet);

           (this.DataSet as IFeatureSet).Filename = this.AbsFileName;



        }


        public override void SaveEntity()
        {
            try
            {
                (this.DataSet as IFeatureSet).SaveAs(this.AbsFileName, true);
            }
            catch (Exception ex)
            { 
            }
            
        }

        public override void LoadEntity()
        {
            try
            {
                //this.DataSet = (FeatureSet)FeatureSet.OpenFile(this.AbsFileName);
                (this.DataSet as FeatureSet).Open(this.AbsFileName); //刘改，把上句改成了这句
            }
            catch (Exception ex)
            {
                
                this.Configure();

                foreach (FShape shp in this.m_Shapes.Values)
                {
                    Shape polyshp = new Shape(this.m_Type);
                    if (this.m_Type == FeatureType.Point)
                    {
                        Coordinate pt = shp.normalPts[0];
                        polyshp = new Shape(pt);
                    }
                    else
                    {
                        polyshp.AddPart(shp.normalPts.ToArray(), CoordinateType.Regular);
                    }
                    Feature f = new Feature(polyshp);

                    if (f != null)
                        (this.DataSet as IFeatureSet).Features.Add(f);
                    f.DataRow["id"] = shp.Id;
                    f.DataRow["desc"] = shp.descString;
                     

                }
            }
            
        }


        /// <summary>
        /// 用于验证shape类是否有效
        /// </summary>
        /// <param name="shp"></param>
        /// <returns></returns>
        public virtual bool IsValidShape(FShape shp)
        {
            if (shp.normalPts .Count <1)
            {
                return false ;
                
            }

            if (this.m_Type ==FeatureType .Line )
            {
                if (shp.normalPts.Count < 2)
                {
                    return false;

                }

            }


            if (this.m_Type == FeatureType.Polygon )
            {
                if (shp.normalPts.Count < 3)
                {
                    return false;

                }

            }


            return true;

 
        }

        [NonSerialized]
        private List<IFeature> _selectedFeatures;

        /// <summary>
        /// 添加图形
        /// </summary>
        public virtual  void AddShape(FShape  shp)
        {

            ///不合格的就直接返回
            if (!this.IsValidShape (shp))
            {
                return;
                
            }

            this.Shapes.Add(shp.Id, shp);  //刘加这句

            Shape polyshp = new Shape(this.m_Type );
            if (this.m_Type == FeatureType.Point)
            {
                Coordinate pt = shp.normalPts[0];
                polyshp = new Shape(pt);
            }
            else
            {
                polyshp.AddPart(shp.normalPts.ToArray(), CoordinateType.Regular);
            }
            Feature f = new Feature(polyshp);

            if (f != null)
                (this.DataSet as IFeatureSet).Features.Add(f);
            f.DataRow["id"] = shp.Id;
            f.DataRow["desc"] = shp.descString;

            if (this.m_ParenLManager.MFSys.SelectedID != null)
            {
                foreach (string id in this.m_ParenLManager.MFSys.SelectedID)
                {
                    if (shp.Id == id)
                    {
                        if (this._selectedFeatures == null) this._selectedFeatures = new List<IFeature>();
                        this._selectedFeatures.Add(f);
                    }
                }

            }
            (this.DataSet as FeatureSet).InvalidateVertices();

            (this.DataSet as FeatureSet).InvalidateEnvelope();


        }

        /// <summary>
        /// 大面积添加图形，借此提高添加读写的效率
        /// </summary>
        /// <param name="lstShp"></param>
        public virtual void AddShapeRange(List<FShape> lstShp)
        {

            for (int i = 0; i < lstShp.Count; i++)
            {
                this.AddShape(lstShp[i]);
            }


            if (this.m_ParenLManager.MFSys.SelectedID != null && this._selectedFeatures != null)
            {
                (this.ILayer as IFeatureLayer).UnSelectAll();
                foreach (IFeature f in this._selectedFeatures)
                {
                    (this.ILayer as IFeatureLayer).Select(f);
                }
            }

            if (this._selectedFeatures != null) _selectedFeatures.Clear();

            (this.DataSet as FeatureSet).InvalidateVertices();

            (this.DataSet as FeatureSet).InvalidateEnvelope();
 
        }

        /// <summary>
        /// 去除图形,根据用户的选择去掉某一图形,这一功能提供给了底层的普通shape文件
        /// </summary>
        public virtual void RemoveShape(string id)
        {
            foreach (IFeature f in (this.DataSet as IFeatureSet).Features)
            {
                if (f.DataRow["id"].ToString() == id)
                {
                    (this.DataSet as IFeatureSet).Features.Remove(f);
                    this.m_Shapes.Remove(id);
                    break;
                }
            }
 
        }

       
        /// <summary>
        /// 自定义FShape对应的Feature的修改
        /// </summary>
        /// <param name="Shp"></param>
        private void ChangeFeature(FShape NewShp)
        {
            foreach (IFeature f in (this.DataSet as IFeatureSet).Features)
            {
                if (f.DataRow["id"].ToString() == NewShp.Id)
                {                    
                    Shape polyshp = new Shape(this.m_Type);
                    if (this.m_Type == FeatureType.Point)
                    {
                        Coordinate pt = NewShp.normalPts[0];
                        polyshp = new Shape(pt);
                    }
                    else
                    {
                        polyshp.AddPart(NewShp.normalPts.ToArray(), CoordinateType.Regular);
                    }
                    Feature newf = new Feature(polyshp);
                    //因为无法得知是移动了shp还是修改了shp的形状或坐标
                    //所以对创建一个新的Feature,将新Feature的坐标直接赋给旧的Feature
                    //这样还可以保证字段selectedFeatures——已选择的Feature 的同步修改（因为是引用传递）
                    f.Coordinates = newf.Coordinates;

                    break;
                }
            }
                     
        }

        /// <summary>
        /// 修改图形！这里的思路发生了些变化
        /// 不再是付以前那种删除原来的图形，填加一个新图形
        /// 而是保留原来的图形，修改其坐标
        /// </summary>
        /// <param name="Shp"></param>
        public virtual void ModifyShape(FShape NewShp)
        {
            if (this.m_Shapes.ContainsKey(NewShp.Id))
            {
                this.m_Shapes.Remove(NewShp.Id);   //NewShp的ID是等于旧Shp的ID的

                this.m_Shapes.Add(NewShp.Id, NewShp);
            }

            //自定义FShape对应的Feature的修改
            this.ChangeFeature(NewShp);


            //-------------------------------------//
            //下面是原来的思路

            //this.RemoveShape(id);
            //this.AddShape(Shp);
            
        }
           
        /// <summary>
        /// 获得shape依赖id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public FShape GetShapeByID(string id)
        {
            if (this.m_Shapes.ContainsKey(id))
            {
                return this.m_Shapes[id];
            }
            else
            {
                return null;
            }
        }


        

        /// <summary>
        /// 清空所有图形,实现底层的晴空操作
        /// </summary>
        public virtual void ClearShapes()
        {
            this.Shapes.Clear();

            (this.DataSet as IFeatureSet).Features.Clear();
 
        }


        /// <summary>
        /// 主要是用来单个图层要关闭一些参数
        /// </summary>
        public override void CloseLayer()
        {
            base.CloseLayer();
        }
    
    }
}
